package com.nbsaas.boot.order.service;

import com.nbsaas.boot.order.data.entity.Order;
import com.nbsaas.boot.order.data.mapper.OrderQueryMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 订单查询服务类
 * 使用Freemarker动态生成
 */
@Service
@Transactional(readOnly = true)
public class OrderQueryService {

    @Resource
    private OrderQueryMapper orderQueryMapper;

    /**
     * 根据店铺和状态查询订单
     * @param shopId 店铺ID
     * @param orderState 订单状态
     * @return 订单列表
     */
    public List<Order> findOrdersByShopAndState(Long shopId, Integer orderState) {
        return orderQueryMapper.findOrdersByShopAndState(shopId, orderState);
    }

    /**
     * 获取订单统计信息
     * @param shopId 店铺ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 统计结果
     */
    public Map<String, Object> getOrderStatistics(Long shopId, LocalDateTime startDate, LocalDateTime endDate) {
        return orderQueryMapper.getOrderStatistics(shopId, startDate, endDate);
    }

    /**
     * 根据客户查询订单
     * @param customerId 客户ID
     * @param shopId 店铺ID
     * @return 客户订单列表
     */
    public List<Order> findOrdersByCustomer(Long customerId, Long shopId) {
        return orderQueryMapper.findOrdersByCustomer(customerId, shopId);
    }

    /**
     * 根据支付状态查询订单
     * @param payState 支付状态
     * @param shopId 店铺ID
     * @param startDate 开始日期
     * @return 支付订单列表
     */
    public List<Map<String, Object>> findOrdersByPayState(Integer payState, Long shopId, LocalDateTime startDate) {
        return orderQueryMapper.findOrdersByPayState(payState, shopId, startDate);
    }

    /**
     * 按日期分组统计订单
     * @param shopId 店铺ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 按日期分组的统计结果
     */
    public List<Map<String, Object>> getOrderStatisticsByDate(Long shopId, LocalDateTime startDate, LocalDateTime endDate) {
        return orderQueryMapper.getOrderStatisticsByDate(shopId, startDate, endDate);
    }

    /**
     * 查询使用优惠券的订单
     * @param shopId 店铺ID
     * @param startDate 开始日期
     * @return 优惠券使用订单列表
     */
    public List<Map<String, Object>> findOrdersWithCoupon(Long shopId, LocalDateTime startDate) {
        return orderQueryMapper.findOrdersWithCoupon(shopId, startDate);
    }

    /**
     * 查询使用会员卡的订单
     * @param shopId 店铺ID
     * @return 会员卡使用订单列表
     */
    public List<Map<String, Object>> findOrdersWithVipCard(Long shopId) {
        return orderQueryMapper.findOrdersWithVipCard(shopId);
    }

    /**
     * 按来源统计订单
     * @param shopId 店铺ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 按来源分组的统计结果
     */
    public List<Map<String, Object>> getOrderStatisticsBySource(Long shopId, LocalDateTime startDate, LocalDateTime endDate) {
        return orderQueryMapper.getOrderStatisticsBySource(shopId, startDate, endDate);
    }

    /**
     * 查询退款订单
     * @param shopId 店铺ID
     * @return 退款订单列表
     */
    public List<Map<String, Object>> findRefundOrders(Long shopId) {
        return orderQueryMapper.findRefundOrders(shopId);
    }

    /**
     * 查询使用积分的订单
     * @param shopId 店铺ID
     * @param startDate 开始日期
     * @return 积分使用订单列表
     */
    public List<Map<String, Object>> findOrdersWithIntegral(Long shopId, LocalDateTime startDate) {
        return orderQueryMapper.findOrdersWithIntegral(shopId, startDate);
    }

    /**
     * 查询使用红包的订单
     * @param shopId 店铺ID
     * @return 红包使用订单列表
     */
    public List<Map<String, Object>> findOrdersWithRedPacket(Long shopId) {
        return orderQueryMapper.findOrdersWithRedPacket(shopId);
    }

    /**
     * 按小时统计订单
     * @param shopId 店铺ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 按小时分组的统计结果
     */
    public List<Map<String, Object>> getOrderStatisticsByHour(Long shopId, LocalDateTime startDate, LocalDateTime endDate) {
        return orderQueryMapper.getOrderStatisticsByHour(shopId, startDate, endDate);
    }

    /**
     * 按状态统计订单
     * @param shopId 店铺ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 按状态分组的统计结果
     */
    public List<Map<String, Object>> getOrderStatisticsByState(Long shopId, LocalDateTime startDate, LocalDateTime endDate) {
        return orderQueryMapper.getOrderStatisticsByState(shopId, startDate, endDate);
    }

    /**
     * 按支付方式统计订单
     * @param shopId 店铺ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 按支付方式分组的统计结果
     */
    public List<Map<String, Object>> getOrderStatisticsByPayMethod(Long shopId, LocalDateTime startDate, LocalDateTime endDate) {
        return orderQueryMapper.getOrderStatisticsByPayMethod(shopId, startDate, endDate);
    }

    /**
     * 获取订单完成时间统计
     * @param shopId 店铺ID
     * @param startDate 开始日期
     * @return 订单完成时间统计
     */
    public List<Map<String, Object>> getOrderCompleteTimeStatistics(Long shopId, LocalDateTime startDate) {
        return orderQueryMapper.getOrderCompleteTimeStatistics(shopId, startDate);
    }

    /**
     * 动态条件查询订单
     * @param conditions 查询条件
     * @return 订单列表
     */
    public List<Order> findOrdersByConditions(Map<String, Object> conditions) {
        return orderQueryMapper.findOrdersByConditions(conditions);
    }

    /**
     * 构建动态查询条件
     * @param shopId 店铺ID
     * @param customerId 客户ID
     * @param orderState 订单状态
     * @param payState 支付状态
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @param minAmount 最小金额
     * @param maxAmount 最大金额
     * @return 查询条件Map
     */
    public Map<String, Object> buildQueryConditions(Long shopId, Long customerId, Integer orderState, 
                                                   Integer payState, LocalDateTime startDate, LocalDateTime endDate,
                                                   BigDecimal minAmount, BigDecimal maxAmount) {
        Map<String, Object> conditions = new java.util.HashMap<>();
        conditions.put("shopId", shopId);
        conditions.put("customerId", customerId);
        conditions.put("orderState", orderState);
        conditions.put("payState", payState);
        conditions.put("startDate", startDate);
        conditions.put("endDate", endDate);
        conditions.put("minAmount", minAmount);
        conditions.put("maxAmount", maxAmount);
        return conditions;
    }

    /**
     * 获取店铺订单总数
     * @param shopId 店铺ID
     * @return 订单总数
     */
    public Long getOrderCountByShop(Long shopId) {
        Map<String, Object> conditions = new java.util.HashMap<>();
        conditions.put("shopId", shopId);
        List<Order> orders = orderQueryMapper.findOrdersByConditions(conditions);
        return (long) orders.size();
    }

    /**
     * 获取店铺订单总金额
     * @param shopId 店铺ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 订单总金额
     */
    public BigDecimal getOrderTotalAmount(Long shopId, LocalDateTime startDate, LocalDateTime endDate) {
        Map<String, Object> statistics = orderQueryMapper.getOrderStatistics(shopId, startDate, endDate);
        Object totalAmount = statistics.get("total_amount");
        return totalAmount != null ? new BigDecimal(totalAmount.toString()) : BigDecimal.ZERO;
    }

    /**
     * 获取店铺已支付订单总金额
     * @param shopId 店铺ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 已支付订单总金额
     */
    public BigDecimal getOrderPayAmount(Long shopId, LocalDateTime startDate, LocalDateTime endDate) {
        Map<String, Object> statistics = orderQueryMapper.getOrderStatistics(shopId, startDate, endDate);
        Object payAmount = statistics.get("total_pay_amount");
        return payAmount != null ? new BigDecimal(payAmount.toString()) : BigDecimal.ZERO;
    }

    /**
     * 获取店铺平均订单金额
     * @param shopId 店铺ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 平均订单金额
     */
    public BigDecimal getOrderAverageAmount(Long shopId, LocalDateTime startDate, LocalDateTime endDate) {
        Map<String, Object> statistics = orderQueryMapper.getOrderStatistics(shopId, startDate, endDate);
        Object avgAmount = statistics.get("avg_amount");
        return avgAmount != null ? new BigDecimal(avgAmount.toString()) : BigDecimal.ZERO;
    }
} 